package com.hanxiaozhang.io.sockettcp;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

/**
 * 〈一句话功能简述〉<br>
 * 〈使用Socket演示Tcp三次握手〉
 * <p>
 * Tips：三次握手发送在内核态，操作系统去执行握手操作。
 *      以下演示的程序，已经完成了三次握手，在用户态发送数据了。
 *
 * @author hanxinghua
 * @create 2023/5/31
 * @since 1.0.0
 */
public class TcpClient {

    /**
     * 服务器监听的端口号
     */
    private static final int PORT = 56002;
    private static final int TIMEOUT = 15000;

    public static void main(String[] args) {

        Socket client = null;
        try {

            // 调用无参构造方法
            client = new Socket();
            // 构造服务器地址结构
            SocketAddress serverAddr = new InetSocketAddress("127.0.0.1", PORT);
            // 连接服务器，超时时间是 15 毫秒
            client.connect(serverAddr, TIMEOUT);
            System.out.println("Client start: " + client.getLocalSocketAddress().toString());

            // 向服务器发送数据  client SYN
            String req = "SYN seq 543067661";
            TcpUtil.sendMsg(client, req);
            System.out.println("Client Send to server: " + req);

            // 接收服务器的数据 server SYN + ACK
            String msg = TcpUtil.receiveMsg(client);
            System.out.println("Client Recv from server: " + msg);


            // 向服务器发送数据  client ACK
            req = "ACK ack 3824468341";
            TcpUtil.sendMsg(client, req);
            System.out.println("Client Send to server: " + req);


            // ---- 通信  ----
            req = "Hello,Nice to meet you";
            TcpUtil.sendMsg(client, req);
            System.out.println("Client Send to server: " + req);

            msg = TcpUtil.receiveMsg(client);
            System.out.println("Client Recv from server: " + msg);

            req = "Bye";
            TcpUtil.sendMsg(client, req);
            System.out.println("Client Send to server: " + req);

            msg = TcpUtil.receiveMsg(client);
            System.out.println("Client Recv from server: " + msg);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
